#include <Game/Game.h>
#include "linkmanager.h"
#include <map>
#include <string>
#include <Skills/link.h>
#include <algorithm>
#include <Skills/typeEnergy.h>

using namespace std;

namespace entity {
    EnergyManager::EnergyManager() : Entity() {
        this->setName("EnergyManager");
        this->learnSkill(new skill::SetTransfer);
        this->learnSkill(new skill::ProduceManage);
        this->hidden = true;
        toTransfer.clear();
    }
    void EnergyManager::setTransfer() {
        std::map<std::string, int> energy;
        std::vector<std::vector<std::string> >::iterator transIt;
        std::map<std::string,int>::iterator it;
        {
            std::map<std::string, int> energyTransfered;
            for (int i = 0; i < toTransfer.size(); ++i)
                energyTransfered[toTransfer[i][0]] = 0;
            for (int i = 0; i < toTransfer.size(); ++i)
                energyTransfered[toTransfer[i][0]] += std::stoi(toTransfer[i][2]);
            for (auto it: energyTransfered){
                int transport_capacity = std::stoi(g->entityManager.findEntityByID(it.first)->properties["transport_capacity"]);
                if (transport_capacity < it.second){
                    toTransfer.erase(remove_if(toTransfer.begin(), toTransfer.end(),
                                               [it](vector<string> x){return x[0] == it.first;}),
                                     toTransfer.end());
                }
            }
        }
        while(true){
            energy.clear();
            Entity *node;
            for(int i = 0; i < toTransfer.size(); ++i) {
                node= g->entityManager.findEntityByID(toTransfer[i][0]);
                energy[toTransfer[i][0]] = std::stoi(node->properties["energy"]);
                node= g->entityManager.findEntityByID(toTransfer[i][1]);
                energy[toTransfer[i][1]] = std::stoi(node->properties["energy"]);
            }
            for(int i = 0; i < toTransfer.size(); ++i){
                energy[toTransfer[i][0]] -= std::stoi(toTransfer[i][2]);
                energy[toTransfer[i][1]] += std::stoi(toTransfer[i][2]);
            }
            bool illegal = false;
            for(it = energy.begin(); it != energy.end(); ++it) {
                if(it->second < 0){
                    toTransfer.erase(remove_if(toTransfer.begin(), toTransfer.end(),
                                               [it](vector<string> x){return x[0] == it->first;}),
                                    toTransfer.end());
                    illegal = true;
                }
            }
            if(!illegal) break;
        }
        Entity *node;
        for(it = energy.begin(); it != energy.end(); ++it){
            node= g->entityManager.findEntityByID(it->first);
            node->properties["energy"] = std::to_string(it->second);
        }
        toTransfer.clear();
    }
}
